package edu.office.applicationRepository;

import edu.office.entities.*;
import edu.office.tools.EOMessage;
import edu.office.tools.EOMessage1;
import edu.office.tools.PersonalSessionSetup;
import edu.office.tools.StaticFields;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.servlet.http.Part;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.*;


@Named("questionRepositoryA")
@ApplicationScoped
public class QuestionRepository extends ApplicationCommonRepository<Question> {
    public final static String SCHOOLNAMESTUDENTNAME = "SCHOOLNAMESTUDENTNAME", STUDENTNAME = "STUDENTNAME";
    public final static int[] questionIndexs = {1, 2, 3, 4, 5, 6, 7};
    final String splitInputOutputTest = "====";
    final String folder = "subjective";
    private final String tableName = "question", imageFile = "QuestionsImage";
    private final double standardAccuracy = 0.8;
    private final String trueAnswer = "T", falseAnswer = "F";
    protected Question current;
    @Inject
    StudentRepository applicationStudent;
    @Inject
    ParentRepository applicationParent;
    @Inject
            LeadpointRepository leadpointRepository;

    //show the corresponding answer on the pages after practice
    String[] replacedAnser = new String[]{"A", "B", "C", "D"};
    /*
    for getAGTP自动生成试卷, one can refer to the paper "Auto-generated Test paper based on Knowledge Embedding"
     */
    Random random = new Random();
    //=================处理学生试卷==============开始=======
    Studenttestpaper temStored = new Studenttestpaper();//用于检测是否重复查询
    ArrayList testQuestions = new ArrayList();
    @Inject
    ReexaminationRepository reexaminationRepository;
    @Inject
    KnowledgeRepository knowledgeRepository;
    @Inject
    SubjectRepository subjectRepository;
    //show the corresponding answer on the pages after practice
    String result = "";
    @Inject
    private ReexaminationRepository applicationReexaminationController;
       @Inject
    private PersonalSessionSetup personalSessionSetup;
       @Inject
    private KnowledgeRepository applicationKnowledgeController;
    @Inject
    private QuestionRepository applicationQuestionController;
    @Inject
    private StatusofresourcesRepository applicationStatusofresourcesController;
    @Inject
    private SubjectRepository applicationSubjectController;
    @Inject
    private RoleinfoRepository applicationRoleinfoController;
    @Inject
    private TeacherAdminRepository applicationTeacherAdmin;

    private String searchName;
    private List<Question> searchedQuestionsList;
    private String[] multSelectionStrings;
    private Part imagePart = null;
    private boolean btnFlag = false;
    //从myPublishedQuestion来调用Edit和View页面
    private boolean fromPublished = false;

    public QuestionRepository() {
    }

    //==========================处理学生试卷==============结束 =======
    public Set<Question> getQuestions4Subject(Subject subject) {
        Set<Question> result = new HashSet<>();
        List<Knowledge> knowledgesList = knowledgeRepository.getKnowledgeList4Subject(subject);
        knowledgesList.forEach((knowledge) -> result.addAll(find("KNOWLEDGE_ID", knowledge.getID()).list()));
        return result;
    }

    public String getAnswer(Question question) {
        //包装选择题，包括单项选择和多项选择题。把选择题的答案1，2转换为A，B
        String result = "";
        try {
            switch (question.getTYPE()) {
                case StaticFields.SINGLESELECTION:
                    result = getCharacter4Number(question.getANSWER());
                    break;
                case StaticFields.MULTISELECTION:
                    String[] tem = question.getANSWER().split(",");
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < tem.length - 1; i++) {
                        sb.append(getCharacter4Number(tem[i]));
                        sb.append(",");
                    }
                    sb.append(getCharacter4Number(tem[tem.length - 1]));
                    result = sb.toString();
                    break;
                case StaticFields.JUDGMENT:
                    if (question.getANSWER().trim().equals("T")) {
                        result = "True";
                    } else {
                        result = "False";
                    }
                    break;
                default:
                    result = question.getANSWER();
                    break;
            }
        } catch (Exception e) {
            System.out.println("getAnswer");
        }
        return result;
    }

    public List<Question> getQuestion4Student(Student student) {
        return getReexaminQuestions4User(student.getId(), false);
    }

    public List<Question> getQuestion4Teacher(TeacherAdmin teacher) {
        return getReexaminQuestions4User(teacher.getID(), true);
    }

    private List<Question> getReexaminQuestions4User(Integer userId, boolean isTeacher) {
        List<Reexamination> reexaminations = reexaminationRepository.getReexaminationId2Examin(userId, isTeacher, null);
        StringBuilder sb = new StringBuilder();
        reexaminations.forEach(reex -> sb.append(reex.getQUESTIONID()));
        return find("select * from question where id in (" + sb + ")").list();
    }

    public List<Question> getQuestion4Knowledge(Knowledge knowledge) {
        return find("KNOWLEDGE_ID", knowledge.getID()).list();
    }

    public boolean isSimpleAnswer(int type) {
        return type == StaticFields.SIMPLEANSWER;
    }

    public boolean isSingleFill(int type) {
        return type == StaticFields.SINGLEFILL;
    }

    public boolean isSingleSelection(int type) {
        return type == StaticFields.SINGLESELECTION;
    }

    public boolean isJudgment(int type) {
        return type == StaticFields.JUDGMENT;
    }

    public boolean isObjectiveProgram(int type) {
        return type == StaticFields.OBJECTIVEPROGRMA;
    }

    public boolean isMultiSelection(int type) {
        return type == StaticFields.MULTISELECTION;
    }

    public boolean isSubjectiveProgram(int type) {
        return type == StaticFields.SUBJECTIVEPROGRAM;
    }

    private void removeStyle(Question question) {
        if (question.getANALYSIS().contains("<td")) {
            question.setANALYSIS(StaticFields.replaceCommonStyle(question.getANALYSIS()));
        }
        if (question.getANSWER().contains("<td")) {
            question.setANSWER(StaticFields.replaceCommonStyle(question.getANSWER()));
        }
        if (question.getVALUEINFO().contains("<td")) {
            question.setVALUEINFO(StaticFields.replaceCommonStyle(question.getVALUEINFO()));
        }
    }

    public int getNumber(Question question) {
        return switch (question.getTYPE()) {
            case StaticFields.SIMPLEANSWER, StaticFields.SINGLEFILL, StaticFields.JUDGMENT, StaticFields.OBJECTIVEPROGRMA, StaticFields.SUBJECTIVEPROGRAM ->
                    1;
            case StaticFields.SINGLESELECTION -> 4;
            case StaticFields.MULTISELECTION -> question.getSECONDCONTENT().split("$#").length;
            default -> 0;
//            case StaticFields.MULTIFILL:
//                numberResult = question.getAnswer().split(StaticFields.THIRDDELIMITED).length;
//                break;
        };
    }

    public String getShownQuestionAnswer(Question question) {
        if (null == question.getANSWER()) {//只查看试卷，学生尚未作答
            return "";
        }
        String answerString;
        answerString = question.getANSWER();
        if (isSingleSelection(question.getTYPE()) || isMultiSelection(question.getTYPE())) {
            String[] ans = answerString.split(",");
            result = "";
            for (String si : ans) {
                result += "," + replacedAnser[Integer.parseInt(si) - 1];
            }
            answerString = result.substring(1);
        }
        return answerString;
    }

    public boolean isSelectionQuestion(int type) {
        return isSingleSelection(type) || isMultiSelection(type);
    }

    public boolean isTextare(int type) {
        return type == StaticFields.SINGLEFILL || type == StaticFields.SIMPLEANSWER;
    }

    public String getCharacter4Number(String index) {
        return String.valueOf((char) ('@' + Integer.parseInt(index)));//@加1得到A
    }


    public HashMap<String, Integer> getQuestionTypeNumberMap(Subject subject) {
        HashMap<String, Integer> qtnm = new HashMap<>();
        List typeList = find(
                "select count(*),type from question where knowledge_id in ("
                        + subjectRepository.getKnowlegeIdsString(subject) + " group by(type))").list();
        for (Object object : typeList) {
            Integer value = (Integer) object;
            qtnm.put("QuestionTypetype", value);//type
        }
        return qtnm;
//            switch (value) {
//                case 1:
//                    qtnm.put(commonSession.getResourceBound().getString("QuestionType1"), value);
//                    break;
//                case 2:
//                    qtnm.put(commonSession.getResourceBound().getString("QuestionType2"), value);
//                    break;
//                case 3:
//                    qtnm.put(commonSession.getResourceBound().getString("QuestionType3"), value);
//                    break;
//                case 4:
//                    qtnm.put(commonSession.getResourceBound().getString("QuestionType4"), value);
//                    break;
//                case 5:
//                    qtnm.put(commonSession.getResourceBound().getString("QuestionType5"), value);
//                    break;
//                case 6:
//                    qtnm.put(commonSession.getResourceBound().getString("QuestionType6"), value);
//                    break;
//                case 7:
//                    qtnm.put(commonSession.getResourceBound().getString("QuestionType7"), value);
//                    break;
//                case 8:
//                    qtnm.put(commonSession.getResourceBound().getString("QuestionType8"), value);
//                    break;
//            }

    }
//<!--单选题-->
//                <h:selectOneRadio value="#{questionRepository.selected.answer}" readonly="#{cc.attrs.readonlyTureFalse}" 
//                                  rendered="#{questionRepositoryA.isType(questionRepository.selected,3)}">
//                    <f:selectItems value="#{questionRepositoryA.secondContentOptions(questionRepository.selected)}"/>
//                </h:selectOneRadio>
//                <!-- 多选题 -->
//                <h:selectManyCheckbox value="#{questionRepository.multSelectionStrings}" readonly="#{cc.attrs.readonlyTureFalse}"
//                                      rendered="#{questionRepositoryA.isType(questionRepository.selected,6)}">
//                    <f:selectItems value="#{questionRepositoryA.secondContentOptions(questionRepository.selected)}"/>
//                </h:selectManyCheckbox>

    public String getQuestionSize4Knowledge(Knowledge knowledge) {
        int number = 0;
        HashSet<Integer> questionType = new HashSet<>();
        List<Question> temQuestions = getQuestion4Knowledge(knowledge);
        if (!temQuestions.isEmpty()) {
            number = temQuestions.size();
        }
        temQuestions.forEach((question) -> questionType.add(question.getTYPE()));
        StringBuilder sb = new StringBuilder();
        questionType.forEach(name -> {
            sb.append(",");
            sb.append(name);
        });
        return number + sb.toString();
    }



    public void search(String searchName, Subject subject) {
        String whereString = " and  KNOWLEDGE_ID in(" + applicationSubjectController.getKnowlegeIdsString(subject) + ")";
        List<Question> searchedResult = applicationQuestionController.list("select * from question where "
                + " (locate('" + searchName.toLowerCase() + "',LOWER(answer))>0 or "
                + " locate('" + searchName.toLowerCase() + "',LOWER(valueinfo))>0 or "
                + " locate('" + searchName.toLowerCase() + "',LOWER(analysis))>0 or "
                + " locate('" + searchName.toLowerCase() + "',LOWER(secondcontent))>0)"
                + whereString
        );


    }

    public String showedName(Question question) {
        StringBuilder sb = new StringBuilder();
        Reexamination reexamination;
        if (null != question) {
            Set<Reexamination> setOfReexaminations = applicationReexaminationController.getReexamination4Question(question);
            if (setOfReexaminations.size() > 0) {
                reexamination = (Reexamination) setOfReexaminations.toArray()[0];
            } else {
                return "";
            }
            TeacherAdmin teacher = applicationTeacherAdmin.find("ID", reexamination.getTEACHERID()).firstResult();
            if (null != teacher) {
                sb.append(null == teacher.getSECONDNAME() ? "" : teacher.getSECONDNAME())
                        .append(" ")
                        .append(null == teacher.getFIRSTNAME() ? "" : teacher.getFIRSTNAME());
            } else {
                Student student = applicationStudent.find("ID", reexamination.getSTUDENTID()).firstResult();
                if (null != student) {
                    sb.append(null == student.getSecondname() ? "" : student.getSecondname())
                            .append(" ")
                            .append(null == student.getFirstname() ? "" : student.getFirstname());
                } else {
                    Parent parent = applicationParent.find("ID", reexamination.getPARENTID()).firstResult();
                    if (null != parent) {
                        sb.append(null == parent.getSECONDNAME() ? "" : parent.getSECONDNAME())
                                .append(" ")
                                .append(null == parent.getFIRSTNAME() ? "" : parent.getFIRSTNAME());
                    }
                }
            }
        } else {
            sb.append("");
        }
        return sb.toString();
    }

    public String MyCreate(Question question, Part imagePart,User user) {

        //1. check whether the name existed? If true, deny the operation;else continue;
        if (applicationQuestionController.list("VALUEINFO", question.getVALUEINFO().trim()).isEmpty()) {
            applicationQuestionController.create(question);
            saveQuestionImages(imagePart, question);
            reexaminationRepository.createReexamination(null, question,user);
            return EOMessage.getEOMessageENUM(EOMessage1.Succeed);
        } else {
            return question.getVALUEINFO() + ":" + EOMessage.getEOMessageENUM(EOMessage1.Already_Exist);
        }
    }

//===================Question Type==========

    public String imageURL(Question question) {
        //System.out.println(imageFile + "/" + getSelected().getKnowledgeId().getId() + "/" + current.getFigure());
        return imageFile + "/" + question.getKNOWLEDGE_ID() + "/" + question.getFIGURE();
    }

    private void saveQuestionImages(Part imagePart, Question question) {
        if (imagePart != null) {
            try (InputStream is = imagePart.getInputStream()) {
                File file = new File(personalSessionSetup.getFilePath() + "/" + imageFile + "/" + question.getKNOWLEDGE_ID());
                // System.out.println("1==============" + picturePath + "/" + current.getKnowledgeId().getId() + ":" + "========================");
                if (!file.exists()) {
                    file.mkdir();
                }
                String filename = imagePart.getSubmittedFileName();
                //If there is some other figures with the same name, then delete it.
                {//For the update
                    //First read all the files name in this fold
                    File[] files = file.listFiles();
                    if (null != files) {
                        //Second, remove those files with the same name with the same name
                        for (int i = 0; i < files.length; i++) {
                            //String temFileName = files[i].getName().substring(0, files[i].getName().indexOf("."));
                            if (files[i].getName().substring(0, files[i].getName().indexOf(".")).equals(String.valueOf(question.getID()))) {
                                files[i].delete();
                            }
                        }
                    }
                }
                filename = question.getID() + filename.substring(filename.lastIndexOf("."));
                Files.copy(is, new File(personalSessionSetup.getFilePath() + "/" + imageFile + "/" + question.getKNOWLEDGE_ID(), filename).toPath());
                question.setFIGURE(filename);
                Reexamination reexamination = (Reexamination) applicationReexaminationController.getReexamination4Question(current).toArray()[0];
                reexamination.setSTATUS(0);//0表示未审核
                applicationQuestionController.edit();
                applicationReexaminationController.edit();
            } catch (Exception e) {
                System.out.println("QuestionController--saveQuestionImages");
            }
            //current.setFigure(folder);
        }
    }
    // String result = "";

    private String setMultiSelectionAnswer(Question question) {
        String tem = "";
        //这里的multSelectionStrings不调用其get方法，因为其get方法会读取原题目中的内容，而不是set过来的最新内容
        for (int i = 0; i < this.multSelectionStrings.length; i++) {
            tem += "," + this.multSelectionStrings[i];
        }
        if (tem.trim().length() > 0) {
            question.setANSWER(tem.substring(1));
        } else {
            return EOMessage.getEOMessageENUM(EOMessage1.Failed);
        }
        return EOMessage.getEOMessageENUM(EOMessage1.Succeed);
    }

    public String update(Question question, Part imagePart,User user) {
        try {
            saveQuestionImages(imagePart, question);
            applicationQuestionController.edit();
            Set<Reexamination> setOfReexaminations = applicationReexaminationController.getReexamination4Question(question);
            if (setOfReexaminations.isEmpty()) {
                Reexamination reexamination = (Reexamination) setOfReexaminations.toArray()[0];
                reexamination.setSTATUS(0);//0表示未审核
                applicationReexaminationController.edit();
            } else {
                reexaminationRepository.createReexamination(null, current,user);
            }
            return EOMessage.getEOMessageENUM(EOMessage1.Succeed);
        } catch (Exception e) {
            return EOMessage.getEOMessageENUM(EOMessage1.Failed);
        }
    }

    public List<Question> getQuestionList4Knowledge(Knowledge knowledge, int questionType) {
        return getQuestionList(knowledge, null, questionType);
    }

    public List<Question> getQuestionList4Subject(Subject subject, int questionType) {
        return getQuestionList(null, subject, questionType);
    }

    private List<Question> getQuestionList(Knowledge knowledge, Subject subject, int questionType) {
        //Get the knowledges of the current subject
        List<Question> questionList = new LinkedList<>();
        List<Knowledge> knowledgeList = new LinkedList<>();
        if (knowledge == null) {
            knowledgeList = applicationKnowledgeController.getKnowledgeList4Subject(subject);
            for (Knowledge knowledge1 : knowledgeList) {
                questionList.addAll(applicationQuestionController.getQuestion4Knowledge(knowledge1));
            }
        } else {
            questionList.addAll(applicationQuestionController.getQuestion4Knowledge(knowledge));
        }
        searchedQuestionsList = new LinkedList<>();
        //prepare question filter
        String whereType = "0";//00=0,01=1,10=2,11=3
        //没有选择知识点
        if (knowledge == null) {
            whereType = "0";//0
        } else {//选择知识点
            whereType = "1";//1
        }
        if (0 == questionType) {//没有选择题型
            whereType += "0";//00 or 10
        } else {//选择题型
            whereType += "1";//01 or 11
        }
        switch (whereType) {
            case "00"://neither knowledge nor quesitontype are selected, all questions are  returned
                searchedQuestionsList = questionList;
                break;
            case "01"://no knowledge selected but questionType is selected
                for (Question question : questionList) {
                    if (question.getTYPE() == questionType) {
                        searchedQuestionsList.add(question);
                    }
                }
                break;
            case "10"://选择了知识点 but no questionType
                for (Question question : questionList) {
                    if (question.getKNOWLEDGE_ID().equals(knowledge)) {
                        searchedQuestionsList.add(question);
                    }
                }
                break;
            case "11"://both knowledge and questionType are selected
                for (Question question : questionList) {
                    if (question.getKNOWLEDGE_ID().equals(knowledge) && question.getTYPE() == questionType) {
                        searchedQuestionsList.add(question);
                    }
                }
                break;
            default:
                searchedQuestionsList = questionList;
        }
        return Optional.ofNullable(searchedQuestionsList).orElse(new LinkedList<>());
    }


    //===============获取多项选择题目的选项===============
    public String[] getSelectionOptionStrings(Question question) {
        String[] answer = null;
        if (applicationQuestionController.isSelectionQuestion(question.getTYPE())) {
            answer = question.getSECONDCONTENT().split("\\$#");
        }
        return answer;
    }

    public String[] getSelectionOptionStrings4Multi(Question question) {
        String[] multAnswer = null;
        String[] backupStrings = new String[5];
        if (applicationQuestionController.isSelectionQuestion(question.getTYPE())) {
            backupStrings = question.getSECONDCONTENT().split("\\$#");
        }
        if (backupStrings.length == 4) {//有4个选项
            multAnswer = new String[5];
            System.arraycopy(backupStrings, 0, multAnswer, 0, 4);
            multAnswer[4] = "";
        } else {//有5个选项
            multAnswer = backupStrings;
        }
        return multAnswer;
    }

    public boolean hasFigure(Question temQuestion) {
        return null != temQuestion.getFIGURE() && temQuestion.getFIGURE().trim().length() > 0;
    }

    private List<Question> getAGTP(float p, List<Question> questionRepository) {
        List<Question> questionsList = new LinkedList<>();
        questionRepository.forEach((_item) -> {
            if (random.nextFloat() < p) {
                questionsList.add(_item);
            }
        });
        return questionsList;
    }

    /*
    for coarse KEM, one can refer to the paper "Auto-generated Test paper based on Knowledge Embedding"
     */
    public List<Question>[] getTPwithCoarseKEM(int targetScore, List<Question> questionRepository, int size) {
        List<Question>[] myresult = new LinkedList[size];
        int sumscore = 0;
        sumscore = questionRepository.stream().map((question) -> question.getSCORE()).reduce(sumscore, Integer::sum);
        for (int i = 0; i < size; i++) {
            myresult[i] = getAGTP(targetScore / ((float) sumscore), questionRepository);
        }
        return myresult;
    }

    /*
    for fine KEM, one can refer to the paper "Auto-generated Test paper based on Knowledge Embedding"
     */
    public List<Question>[] getTPwithFineKEM(int targetScore, List<Question> questionRepository, int size) {
        List<Question>[] myresult = new LinkedList[size];
        int sumscore = 0;
        sumscore = questionRepository.stream().map((question) -> question.getSCORE()).reduce(sumscore, Integer::sum);
        for (int i = 0; i < size; i++) {
            myresult[i] = getAGTP(targetScore / ((float) sumscore), questionRepository);
        }
        return myresult;
    }

    public String deleteImage(Question question) {
        //删除掉服务器中的文件
        File file = new File(personalSessionSetup.getFilePath() + "/" + imageURL(question));
        if (file.exists()) {
            file.delete();
        }
        //更新数据库的figure值
        applicationQuestionController.edit();
        return null;
    }

    /*
                    表格中判断是什么题型：
                        A 简答题
                        B 填空
                        C 单选
                        D 判断
                        E 客观编程
                        F 多选
                        G 主观编程
                    数据库中判断：
                        1 简答
                        2 填空
                        3 单选
                        4 判断
                        5 客观编程
                        6 多选
                        7 主观编程
     */
    public String uploadQuestions(User user,   Part questionExcel) {
        InputStream in = null;
        Question q = null;
        try {
            if (questionExcel != null) {
                in = questionExcel.getInputStream();
                Workbook book = new HSSFWorkbook(in);
                Sheet sheet = book.getSheetAt(0);
                List<Knowledge> knowledgeList;
                Knowledge knowledge = null;
                Iterator<Row> it = sheet.rowIterator();
                while (it.hasNext()) {
                    Row row = it.next();
                    //int sheetRows = sheet.getRows();
                    //for (int i = 1; i < sheetRows; i++) {
                    q = new Question();
                    //判断数据库是否有此知识点
                    knowledgeList = applicationKnowledgeController.find("select * from knowledge where name='" + row.getCell(3).getStringCellValue().trim() + "'").list();
                    if (!knowledgeList.isEmpty()) {
                        knowledge = knowledgeList.get(0);
                    }
                    //存在的话
                    if (knowledge != null) {
                        //再判断数据库是否有此记录，根据题目内容和知识点id
                        //判断是选择题还是其他题型
                        String questionTypestr = row.getCell(5).getStringCellValue().trim();
                        if (questionTypestr.equals("C")) {
                            //去掉字符串中的换行
                            String questionContent = row.getCell(1).getStringCellValue().trim().replaceAll("\r|\n", "");
                            q.setVALUEINFO(questionContent.substring(0, convertToInt(questionContent, 'A')));
                            if (applicationQuestionController.find("select * from question where knowledge_id=" + knowledge.getID() + " and valueinfo='" + q.getVALUEINFO() + "'").list().isEmpty()) {
                                String answerStr = questionContent.substring(convertToInt(questionContent, 'A'));
                                //加2是因为"A."长度为2，且不需要此串
                                //此处没有使用StringBuffer,会占用更多的内存空间
                                q.setSECONDCONTENT(answerStr.substring(convertToInt(answerStr, 'A') + 2, convertToInt(answerStr, 'B')).trim()
                                        + "$#" + answerStr.substring(convertToInt(answerStr, 'B') + 2, convertToInt(answerStr, 'C')).trim()
                                        + "$#" + answerStr.substring(convertToInt(answerStr, 'C') + 2, convertToInt(answerStr, 'D')).trim()
                                        + "$#" + answerStr.substring(convertToInt(answerStr, 'D') + 2).trim());
                            } else {
                                continue;
                            }

                        } else {
                            q.setVALUEINFO(row.getCell(1).getStringCellValue().trim());
                            if (!applicationQuestionController.find("select * from question where knowledge_id=" + knowledge.getID() + " and valueinfo='" + q.getVALUEINFO() + "'").list().isEmpty()) {
                                continue;
                            }
                        }
                        //都需要设置的属性
                        q.setANSWER(row.getCell(2).getStringCellValue());
                        //如果知识点已经导入数据库，则不会出错，否则则会报错
                        q.setKNOWLEDGE_ID(knowledge.getID());
                        q.setANALYSIS(row.getCell(6).getStringCellValue());
                        //设置题目类型
                        q.setTYPE(judgeQuestionType(questionTypestr));
                        //其他属性设置为默认值
                        q.setDEGREE(2);
                        q.setNEEDTIME(3);
                        q.setSCORE(5);
                        //写入数据库
                        applicationQuestionController.create(q);
                        reexaminationRepository.createReexamination(null, q,user);
                    }
                }
            }
        } catch (IOException ex) {
            System.out.println("QuestionController==IOException");
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                System.out.println("QuestionController--uploadQuestions");
            }
        }
        return null;
    }

    //为了表格中为A. || A． || A、取字符串索引出错
    public int convertToInt(String str, char ch) {
        int strIndex1 = str.indexOf(ch + ".");
        int strIndex2 = strIndex1 == -1 ? str.indexOf(ch + "．") : strIndex1;
        int strIndex3 = strIndex2 == -1 ? str.indexOf(ch + "、") : strIndex2;
        return strIndex3;
    }

    public Integer judgeQuestionType(String qStr) {
        Integer qTypeInteger = 0;
        switch (qStr) {
            case "A":
                qTypeInteger = 1;
                break;
            case "B":
                qTypeInteger = 2;
                break;
            case "C":
                qTypeInteger = 3;
                break;
            case "D":
                qTypeInteger = 4;
                break;
            case "E":
                qTypeInteger = 5;
                break;
            case "F":
                qTypeInteger = 6;
                break;
            case "G":
                qTypeInteger = 7;
                break;
        }

        return qTypeInteger;
    }

    public HashMap<String, Integer> getWrongQuestions() {
        HashMap<String, Integer> result = new HashMap<>();
        //applicationStudenttestpaperController.get.getWrongquestionList()
        //getSelected().getId()
        return result;
    }

    public void startPractice(Knowledge k) {
        List<Question> questions = new ArrayList<>();
        List<Question> allQuestions = new ArrayList<>();
        Set<Question> requiredQuestion = new HashSet<>();
        if (k != null) {
            allQuestions = applicationQuestionController.list("select * from question where knowledge_id=" + k.getID());
        }
        if (allQuestions.isEmpty() || allQuestions.size() <= 10) {
            allQuestions.forEach(e -> {
                questions.add((Question) e);
            });
        } else {
            for (int i = 0; i < 10; i++) {
                int randomQuestion = (int) Math.floor(Math.random() * allQuestions.size());
                requiredQuestion.add(allQuestions.get(randomQuestion));
            }
            questions.addAll(requiredQuestion);
        }
    }

    public String correctAnswer(String[] allAnswers, List<Question> questions, Subject subject, Student student,Leadpoint leadpoint) {
        Set<Question> correctQuestions = new HashSet<>();
        Set<Question> wrongQuestions = new HashSet<>();
        int correctAnswerCnt = 0;
        for (int i = 0; i < 10; i++) {
            if (allAnswers[i].equals(questions.get(i).getANSWER())) {
                correctQuestions.add(questions.get(i));
                correctAnswerCnt++;
            } else {
                wrongQuestions.add(questions.get(i));
            }
        }

        double myAccuracy = correctAnswerCnt / 10;
        if (myAccuracy > standardAccuracy) {
            //更新知识点前沿，直接取得当前知识点所有后继知识点，随机赋值给一个知识点？
            leadpointRepository.updateLeadPoint(correctQuestions, wrongQuestions, subject, student);
            return "此知识点的学习已完成";
        } else {
            //提示正确率不够，请继续努力
            return "正确率不够，请继续努力";
        }
    }

    //在简答题的批改过程中，学生的答案与原答案在页面上完全一样，但仍然判错。
    //由于在前期收集答案时，采用了富文本，所以后台答案中包含\r\n等特殊。
    //解决思路：删除这些特殊字符
    //实现办法：用空字符串替换这些特殊字符。
    public void dealRichText() {
        //读取所有的question
        List<Question> allQuestions = applicationQuestionController.list("select * from question");
        //遍历answer,//替换，不用检查，因为检查会不存在，因为在contanins函数中把转义符给略掉了
        for (Question question : allQuestions) {
            String result = question.getANSWER().replace("\r\n", "");
            question.setANSWER(result);
        }
    }

    private List<Question> getQuestionList(User user, Integer status) {
        List<Question> result = new LinkedList<>();
        if (null != user && null != user.getId()) {
            List<Reexamination> reexaminations = reexaminationRepository.getReexaminationQuestionListRecorderBy(user, status);
            if (reexaminations.size() > 0) {
                StringBuilder sb = new StringBuilder();
                reexaminations.forEach(re -> {
                    sb.append(re.getQUESTIONID()).append(",");
                });
                String ids = sb.toString();
                if (ids.length() > 0) {
                    ids = ids.endsWith(",") ? ids.substring(0, ids.length() - 1) : ids;
                    result = applicationQuestionController.list("select * from Question where id in (" + ids + ")");
                }//result = getFacade().getKnowledge4Student(student);
            }
        }
        return result;
    }

    public List<Question> prepareMyExaminedQuestionList(Integer status, Integer secondStatus,TeacherAdmin user) {
        List<Question> result = null;
        StringBuilder sb = new StringBuilder();
        List<Reexamination> reexaminations = reexaminationRepository.getReexaminationNeedToBeExamined(user, status, 1, secondStatus);
        reexaminations.forEach(re -> {
            sb.append(re.getQUESTIONID()).append(",");
        });
        String ids = sb.toString();
        if (ids.length() > 0) {
            ids = ids.endsWith(",") ? ids.substring(0, ids.length() - 1) : ids;
            result = applicationQuestionController.list("select * from question where id in (" + ids + ")");
        } else {
            result = new LinkedList<>();
        }
        return result;
    }

    public List<Question> getTestQuestion(Studenttestpaper temTestpaper) {
        if (temStored == null || null == temStored.getID() || !temStored.getID().equals(temTestpaper.getID())) {
            //还没开始查询，所以id为空，或者已经发生了改变，所以需要查
            temStored = temTestpaper;
            testQuestions.clear();
            //只有当不相等时，才去检索
            if (temTestpaper != null) {
                if (null != temTestpaper.getQUESTION_IDS()) {
                    String[] questionIds = temTestpaper.getQUESTION_IDS().split(",");
                    for (String questionId : questionIds) {
                        Question tem = applicationQuestionController.find("ID", questionId).firstResult();
                        if (null != tem) {//由于删除某些题目，导致会出现空的情况
                            testQuestions.add(tem);
                        }
                    }
                }
            }
        }
        return testQuestions;
    }
}
